package com.bocai.user.wxauth.api;

import com.bocai.Response;
import com.bocai.ResponseCode;
import com.bocai.user.model.User;
import com.bocai.user.model.vo.AuthInfo;
import com.bocai.user.service.UserService;
import com.bocai.utils.HttpUtils;
import com.bocai.utils.JsonUtils;
import org.apache.log4j.LogManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.Map;

/**
 * 微信授权API
 *
 * @author create by VIC.Huang
 * @date 2018/1/8
 */
@RestController
@RequestMapping("/wxauth")
public class WxAuthApi {
    private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
    private static final String GET_USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";

    @Value("${wx.appid}")
    private String appId;
    @Value("${wx.secret}")
    private String secret;

    @Autowired
    private UserService userService;

    @GetMapping("/wxlogin")
    public Response getUserInfo(@RequestParam("code") String code,
                                @RequestParam(value = "fromuid", required = false, defaultValue = "0") Long fromuid) throws IOException {
        // 用于测试，直接查找指定openid的user
        if (("520".equals(code))) {
            User userInfo = userService.getUserByOpenId("oMpnlsydc2FAwfaBP2WmBwG-c_HY");
            if (null != userInfo) {
                return getLoginResponse(userInfo);
            }
        }

        try {
            //1. 获取access_token
            String accessTokenUrl = ACCESS_TOKEN_URL.replace("APPID", appId).replace("SECRET", secret).replace("CODE", code);
            String resultStr = HttpUtils.get(null, accessTokenUrl);
            Map<String, Object> accessTokenMap = JsonUtils.toMap(resultStr, String.class, Object.class);
            if (accessTokenMap.containsKey("access_token")) {
                //2. 拉取用户信息
                String getUserInfoUrl = GET_USER_INFO_URL
                        .replace("ACCESS_TOKEN", String.valueOf(accessTokenMap.get("access_token")))
                        .replace("OPENID", String.valueOf(accessTokenMap.get("openid")));
                String resultOfUserInfo = HttpUtils.get(null, getUserInfoUrl);
                Map<String, Object> userInfoMap = JsonUtils.toMap(resultOfUserInfo, String.class, Object.class);
                if (userInfoMap.containsKey("openid")) {
                    User userModel = new User();
                    userModel.setNickName(String.valueOf(userInfoMap.get("nickname")))
                            .setWxHeadImg(String.valueOf(userInfoMap.get("headimgurl")))
                            .setWxName(String.valueOf(userInfoMap.get("nickname")));

                    // 判断openid是否已存在库中，是则直接查库更新并返回
                    User userInfo = userService.getUserByOpenId(String.valueOf(userInfoMap.get("openid")));
                    if (null != userInfo) {
                        if(userInfo.getDisable()) {
                            return new Response(ResponseCode.SERVER_ERROR.getValue(), "账户已被禁用！");
                        }else {
                            // 更新用户信息
                            userModel.setId(userInfo.getId());
                            userService.updateWxUser(userModel);
                            return getLoginResponse(userInfo);
                        }
                    }

                    // 注册用户到数据库中
                    userModel.setOpenId(String.valueOf(userInfoMap.get("openid")));
                    if(null != fromuid && 0L != fromuid) {
                        userModel.setFromuid(fromuid);
                    }
                    if(userService.registerWxUser(userModel)) {
                        return getLoginResponse(userModel);
                    }else {
                        return new Response(ResponseCode.SERVER_ERROR.getValue(), "系统有误，授权登录失败！");
                    }
                } else {
                    return new Response(ResponseCode.SERVER_ERROR.getValue(), "获取用户信息失败【" + userInfoMap.get("errmsg") + "】");
                }
            } else {
                return new Response(ResponseCode.SERVER_ERROR.getValue(), "获取用户信息失败【" + accessTokenMap.get("errmsg") + "】");
            }
        } catch (Exception e) {
            LogManager.getLogger(WxAuthApi.class).error("Failed to get userInfo!", e);
            return new Response(ResponseCode.SERVER_ERROR.getValue(), "获取用户信息失败【" + e.getMessage() + "】");
        }
    }

    private Response getLoginResponse(User userInfo) {
        String token = userService.saveLoginInfo(userInfo);
        AuthInfo authInfo = new AuthInfo();
        authInfo.setUserId(userInfo.getId()).setHeadImgUrl(userInfo.getWxHeadImg())
                .setNickname(userInfo.getWxName()).setToken(token);
        return new Response(authInfo);
    }
}




